package DEEPERsource.DEEPERsource.source.machinelearning.kernel;

import deeper.Interaction;
import edu.stanford.nlp.process.Morphology;
import edu.stanford.nlp.trees.WordStemmer;
import edu.uci.ics.jung.graph.DirectedEdge;
import edu.uci.ics.jung.graph.Vertex;
import graph.Keys;

import java.util.Set;

import machinelearning.utils.PorterStemmer;

public class KimKernel implements Kernel<Interaction>, Keys {

	@SuppressWarnings("unchecked")
	public double compute(Interaction i1, Interaction i2){
		double result = 0;
		if(i1.depPath == null || i2.depPath == null){
			return result;
		}
		for(Vertex v1 : i1.depPath.vertices){
			for(Vertex v2 : i2.depPath.vertices){
				result += Cm(v1,v2) + CmPOS(v1,v2);
			}
		}
		return result;
	}
	
	private double Cm(Vertex v1, Vertex v2){
		double result = 1;
		String word1 = (String) v1.getUserDatum(LABEL);
		String pos1 = (String) v1.getUserDatum(POS);
		String word2 = (String) v2.getUserDatum(LABEL);
		String pos2 = (String) v2.getUserDatum(POS);
		String stem1 = Morphology.stemStatic(word1, pos1).word();
		String stem2 = Morphology.stemStatic(word2, pos2).word();
		if(stem1.equals(stem2)){				
			if(v1.getOutEdges().size()>0 && v2.getOutEdges().size()>0){
				for(Object e1 : v1.getOutEdges()){
					for(Object e2 : v2.getOutEdges()){
						if(((DirectedEdge)e1).getUserDatum(Keys.LABEL).equals(((DirectedEdge)e2).getUserDatum(Keys.LABEL))){
							result *= (Cm(((DirectedEdge)e1).getDest(),((DirectedEdge)e2).getDest())+2);
						}
					}
				}
			}
		}
		result--;
		return result;
	}
	
	private double CmPOS(Vertex v1, Vertex v2){
		double result = 1;
		String pos1 = (String) v1.getUserDatum(POS);
		String pos2 = (String) v2.getUserDatum(POS);
		if(pos1.equals(pos2)){				
			if(v1.getOutEdges().size()>0 && v2.getOutEdges().size()>0){
				for(Object e1 : v1.getOutEdges()){
					for(Object e2 : v2.getOutEdges()){
						if(((DirectedEdge)e1).getUserDatum(Keys.LABEL).equals(((DirectedEdge)e2).getUserDatum(Keys.LABEL))){
							result *= (Cm(((DirectedEdge)e1).getDest(),((DirectedEdge)e2).getDest())+2);
						}
					}
				}
			}
		}
		result--;
		return result;
	}
}
